#include "theater.h"

/************************************************
 *
 *  start for ticket taker
 *
 ************************************************/
int  main()
{
    int i;
    int ttId;
    Employee* currentTT;
    int temp;
    int temp1;
    int temp2;
    /* get curTickclerkno */
    initTheater();
    AcquireLock(tickettakerWorknoLock);
    temp=getMV(tickettakerWorkno);
    ttId = temp++;
    currentTT=&tt[ttId];
    currentTT->id = ttId;
    setMV(tickettakerWorkno,temp);
    Printf("tickettaker clerk %d is going to work\n",ttId);
    ReleaseLock(tickettakerWorknoLock);

    while(1)
    {
        /* stop ticket check*/
        /*        lCheckTickets AcquireLock();*/
        AcquireLock(lTicketTaken);
        temp=getMV(stopTicketTaken);
        if ( temp== true)
        {
            AcquireLock(currentTT->lock);
            setMV( stopTicketTakenArr[currentTT->id] , true);
            ReleaseLock(currentTT->lock);
            ReleaseLock(lTicketTaken);
            AcquireLock(lCheckTickets);
            /* broadcast the waiting list*/
            /*BroadcastCV(lCheckTickets,currentTT->lineCondition);*/
            /*            setIsBusy=false;*/
            ReleaseLock(lCheckTickets);
            /* wait for manager to broadcast*/
            AcquireLock(lTicketTaken);
            WaitCV(lTicketTaken,cTicketTaken);
        }
        AcquireLock(currentTT->lock);
        setMV(stopTicketTakenArr[currentTT->id] , false);
        ReleaseLock(currentTT->lock);
        ReleaseLock(lTicketTaken);
        AcquireLock(lCheckTickets);
        if (getMV(currentTT->isBreak))
        {
            /* wait for manager signal*/
            Printf("tickettaker [%d] is going on break.\n", currentTT->id);
            temp=getMV(breakTicketTaker);
            if (!temp) {
                WaitCV(lCheckTickets, cBreakTicketTaker);
            }
            setMV( breakTicketTaker , 0);
            Printf("tickettaker [%d] is coming off break.\n", currentTT->id);
            setMV(currentTT->isBreak,false);

            /*            Printf("TicketTaker [%d] is going on break.\n",currentTT->id);*/
            /*            continue;*/
        }
        temp=getMV(currentTT->waitingSize );
        if (temp> 0)
        {
            Printf("TicketTaker [%d] has a line length [%d] and is signaling a customer.\n",currentTT->id,temp);
            setMV( currentTT->isBusy,true);
            SignalCV(lCheckTickets,currentTT->lineCondition);
        }
        else
        {
            Printf("TicketTaker [%d] has no one in line. I am available for a customer.\n",currentTT->id);
            setMV(currentTT->isBusy,false);
        }
        AcquireLock(currentTT->lock);
        /* on service*/
        ReleaseLock(lCheckTickets);
        /* wait customer to signal*/
        WaitCV(currentTT->lock,currentTT->msgCondition);
	if(true==getMV(closeTheater)){
		ReleaseLock(currentTT->lock);
		break;
	}
        /* if break ? race condition*/
        AcquireLock(lCheckTickets);
        if (currentTT->isBreak && !currentTT->isBusy)
        {
            setMV(currentTT->isBusy,false);
            ReleaseLock(currentTT->lock);
            ReleaseLock(lCheckTickets);
            continue;
        }
        else
        {
            setMV(currentTT->isBusy,true);
        }
        ReleaseLock(lCheckTickets);

        /*get tickets sum*/
        Printf("TicketTaker [%d] has received [%d] tickets.\n",currentTT->id, getMV(currentTT->ticketSum));
        /* if stopped*/
        ReleaseLock(currentTT->lock);
        AcquireLock(lTicketTaken);
        /*        if (stopTicketTaken) {*/
        /*            lTicketTaken ReleaseLock();*/
        /*            continue;*/
        /*        }*/
        /* if too much, has to stop*/
        /* ? if there is another ticketTaker on process, still not stop him*/
        AcquireLock(currentTT->lock);
        temp=getMV(stopTicketTaken);
        temp1=getMV(ticketTaken);
        temp2=getMV(currentTT->ticketSum);
        if (temp || temp1 +temp2 > 25)
        {
            setMV( stopTicketTaken , true);
            setMV( stopTicketTakenArr[currentTT->id] , true);
            Printf("TicketTaker [%d] is not allowing the group into the theater. The number of taken tickets is [%d] and the group size is [%d].\n", currentTT->id, temp1, temp2);
            /* signal the service one*/
            Printf("TicketTaker [%d] has stopped taking tickets.\n", currentTT->id);
            SignalCV(currentTT->lock, currentTT->msgCondition);
            ReleaseLock(currentTT->lock);
            ReleaseLock(lTicketTaken);
            /* broadcast the waiting list*/
            /*AcquireLock(lCheckTickets);
            BroadcastCV(lCheckTickets,currentTT->lineCondition);
            ReleaseLock(lCheckTickets);*/

            continue;
        }
        temp=getMV(currentTT->ticketSum);
        addMVbyValue(ticketTaken ,temp);
        addMVbyValue(totalTicketTaken ,temp);
        Printf("TicketTaker [%d] is allowing the group [%d] into the theater. The number of tickets taken is [%d].\n",currentTT->id,getMV( currentTT->groupId), getMV( ticketTaken));
        ReleaseLock(lTicketTaken);
        /* should just let in, not tell customers seats number*/
        /* better not to enforce seats number, which needs more variables to state*/
        SignalCV(currentTT->lock,currentTT->msgCondition);
        /* customer leave, get next customer*/
        WaitCV(currentTT->lock,currentTT->msgCondition);
        /* put lTicketTaken Release here to avoid race condition;*/
        ReleaseLock(currentTT->lock);
    }
    Exit(0);
}


/************************************************
 *
 *  end for ticket taker
 *
 ************************************************/

